
package com.epam.android.training.level1.poll.parser;

import com.epam.android.training.level1.poll.AnswerBo;
import com.epam.android.training.level1.poll.QuestionBo;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Anton Novikau
 */
public class JsonPollParser implements PollParser {

  private static final String POLL_SET = "polls";

  private static final String POLL_NAME = "poll_name";

  private static final String QUESTIONS = "poll";

  private static final String QUESTION_NAME = "question";

  private static final String CORRECT_ANSWERS = "correct_answers";

  private static final String ANSWERS = "answer";

  @Override
  public Map<String, List<QuestionBo>> parse(InputStream source) throws PollParserException {
    try {
      Map<String, List<QuestionBo>> pollSet = new HashMap<String, List<QuestionBo>>();
      JSONObject root = new JSONObject(readJsonStream(source));
      JSONArray jsonPollSet = root.getJSONArray(POLL_SET);
      int pollSetSize = jsonPollSet.length();
      for (int i = 0; i < pollSetSize; i++) {
        JSONObject jsonPoll = jsonPollSet.getJSONObject(i);
        String pollName = jsonPoll.getString(POLL_NAME);

        JSONArray jsonQuestions = jsonPoll.getJSONArray(QUESTIONS);
        int questionsSize = jsonQuestions.length();
        List<QuestionBo> questions = new ArrayList<QuestionBo>(questionsSize);
        pollSet.put(pollName, questions);
        for (int j = 0; j < questionsSize; j++) {
          QuestionBo question = new QuestionBo();
          questions.add(question);
          JSONObject jsonQuestion = jsonQuestions.getJSONObject(j);
          question.setDisplayName(jsonQuestion.getString(QUESTION_NAME));
          JSONArray jsonAnswers = jsonQuestion.getJSONArray(ANSWERS);
          int answersSize = jsonAnswers.length();
          for (int k = 0; k < answersSize; k++) {
            AnswerBo answer = new AnswerBo();
            answer.setDisplayName(jsonAnswers.getString(k));
            question.addAnswer(answer);
          }
          JSONArray correct = jsonQuestion.getJSONArray(CORRECT_ANSWERS);
          int correctAnswersSize = correct.length();
          List<AnswerBo> answers = question.getAnswers();
          for (int k = 0; k < correctAnswersSize; k++) {
            int correctIndex = correct.getInt(k);
            answers.get(correctIndex).setCorrect(true);
          }
        }
      }

      return pollSet;
    } catch (JSONException e) {
      throw new PollParserException("Unable to parse JSON source", e);
    } catch (IOException e) {
      throw new PollParserException("Unable to read JSON source", e);
    }
  }

  private String readJsonStream(InputStream source) throws IOException {
    byte[] buffer = new byte[source.available()];
    source.read(buffer);
    return new String(buffer);
  }
}
